module recv_data
  #(
     parameter  SYNC1=10'b1010_1010_10,
     parameter  SYNC2=10'b1010_1010_11
   )
   (
     input						rst,
     input						clk_100M	,
     input						clk_400M	,
     input						rx,

     output	reg			ko_100Mr,
     output	reg	[7:0]	rx_data_8b10b_r,
     output	reg			rx_data_en_100Mrr
   );

  wire   rx_bit;
  wire   rx_bit_en;

  reg  [3:0] bit_count;
  reg  [9:0] bit_sft;
  reg  [9:0] sync_shift;

  reg			fr_sync1,fr_sync2;
  reg			fr_sync;

  reg			fr_end;
  reg			fr_end_r; //use fr_end and fr_end_r , convert the "end" signal from clk_100M domain  to clk_400M
  reg			nfr_end_r;
  reg			fr_end_rg;

  reg	[9:0] rx_data;
  reg			rx_data_en;

  reg			rx_data_en_r;

  reg	[9:0] rx_data_100Mr;
  reg			rx_data_en_100Mr;

  wire			ko;
  wire	[7:0] rx_data_8b10b;

  always@(posedge clk_400M or posedge rst)
    if(rst)
    begin
      rx_data		<=0;
      rx_data_en	<=0;
      bit_count	<=0;
      bit_sft		<=0;
      fr_sync1		<=0;
      fr_sync2		<=0;
      fr_sync		<=0;
      fr_end_r		<=0;
      nfr_end_r	<=1'b1;
      fr_end_rg	<=0;
    end

    else
    begin
      if (rx_bit_en)
      begin
        bit_sft		<={bit_sft[8:0],rx_bit};
        sync_shift	<={sync_shift[8:0],bit_sft[9]};
      end

      if(bit_sft==SYNC2)
        fr_sync2<=1'b1;
      else
        fr_sync2<=1'b0;


      if(sync_shift==SYNC1)
        fr_sync1<=1'b1;
      else
        fr_sync1<=1'b0;

      if(fr_end_rg)  //rg==rising edge
        fr_sync<=1'b0;

      else if(fr_sync1&fr_sync2&rx_bit_en)
        fr_sync<=1'b1;

      if(fr_end_rg)
        bit_count<=0;
      else if(fr_sync & rx_bit_en)
      begin

        if(bit_count==9)
          bit_count<=0;
        else
          bit_count<=bit_count+1'b1;
      end

      rx_data_en	<=0;

      if(bit_count==9)
      begin
        rx_data<=bit_sft;
        rx_data_en	<=1'b1;
      end

      fr_end_r	<=fr_end;
      nfr_end_r<=!fr_end_r;
      fr_end_rg<=fr_end_r & nfr_end_r;
    end

  always@(posedge clk_100M)
  begin

    if((ko==1)&&(rx_data_8b10b==8'h3c))    //K28.1
      fr_end<=1'b1;
    else
      fr_end<=0;
  end

  reg  rstx;

  always@(posedge clk_100M)
    rstx<=rst;

  //from clk_400M domain to clk_100M domain sync

  reg [5:0] count_400M;
  reg		  rx_data_en_x;//x---cross clk domain
  reg       nrx_data_en_x;
  reg       rx_data_en_xrg;  //rising edge

  always@(posedge clk_400M or posedge rst)
    if(rst)
    begin
      count_400M				<=0;
      rx_data_en_r		<=0;
    end
    else
    begin
      if(rx_data_en)
        rx_data_en_r	<=1'b1;
      else if(count_400M==19)
        rx_data_en_r	<=1'b0;

      if(count_400M==19)// begin
        count_400M<=0;
      //rx_data_en_r	<=1'b0;
      //end
      else if(rx_data_en_r)
        count_400M<=count_400M+1'b1;
    end

  always@(posedge clk_100M or posedge rst)
    if(rst)
    begin
      rx_data_en_x		<=1'b0;
      nrx_data_en_x		<=1'b1;
      rx_data_en_xrg		<=1'b0;
      ko_100Mr				<=1'b0;
      rx_data_100Mr		<=0;
      rx_data_en_100Mr	<=1'b0;
      rx_data_en_100Mrr	<=1'b0;
      rx_data_8b10b_r	<=8'b0;
    end
    else
    begin
      rx_data_en_x<=rx_data_en_r;
      nrx_data_en_x<=!rx_data_en_x;
      rx_data_en_xrg<=nrx_data_en_x& rx_data_en_x;

      rx_data_en_100Mr<=1'b0;
      if(rx_data_en_xrg)
      begin
        rx_data_100Mr<=rx_data;
        rx_data_en_100Mr<=1'b1;
      end

      ko_100Mr<=ko;
      rx_data_en_100Mrr<=rx_data_en_100Mr;
      rx_data_8b10b_r<=rx_data_8b10b;
    end

  dec_10b8b_pack  dec_10b8b_pack_inst
                  (
                    .clk_100M	(clk_100M),
                    .rst			(rstx),
                    .data_in		(rx_data_100Mr),
                    .ko			(ko),
                    .data_out	(rx_data_8b10b)
                  );

  recv_bit  recv_bit_inst
            (
              .rst			(rst),
              .clk_400M	(clk_400M),
              .rx			(rx),
              .rx_bit		(rx_bit),
              .rx_bit_en	(rx_bit_en),
              .rx_r			(),
              .rx_rr		(),
              .nrx_r		(),
              .nnrx_r		(),
              .rx_rg		(),
              .rx_fg		(),
              .rx_dg		()
            );

endmodule
